<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
    <title>充电记录</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    <!-- Tailwind 配置 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#2563eb',    // 充电中-蓝
                        success: '#10b981',    // 已完成-绿
                        gray: {
                            100: '#f3f4f6',
                            200: '#e5e7eb',
                            300: '#d1d5db',
                            400: '#9ca3af',
                            500: '#6b7280',
                            600: '#4b5563',
                        }
                    },
                    fontFamily: {
                        sans: ['system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    <style type="text/tailwindcss">
        @layer utilities {
            .record-card {
                @apply bg-white rounded-lg border border-gray-200 shadow-sm transition-all duration-200 hover:shadow mb-3;
            }

            .stat-card {
                @apply bg-white rounded-lg border border-gray-200 shadow-sm p-3 flex-1 min-w-[120px] mx-1;
            }

            .status-tag {
                @apply px-2 py-0.5 rounded text-xs font-medium;
            }

            .text-truncate {
                @apply overflow-hidden text-ellipsis whitespace-nowrap;
            }
        }
    </style>
</head>

<body class="bg-gray-50 font-sans text-gray-700 min-h-screen">
<!-- 头部：标题+当前日期 -->
<header class="bg-white border-b border-gray-200 sticky top-0 z-20">
    <div class="container mx-auto px-4 py-3 flex items-center justify-between">
        <h1 class="text-lg font-semibold flex items-center">
            <i class="fa fa-bolt text-primary mr-2"></i>
            充电记录
        </h1>
        <span class="text-xs text-gray-500" id="current-date"></span>
    </div>
</header>
<!-- 核心内容：统计+记录列表 -->
<main class="container mx-auto px-3 py-4">
    <!-- 统计栏：横向滚动适配手机 -->
    <div class="flex overflow-x-auto pb-3 mb-4">
        <!-- 有效订单数 -->
        <div class="stat-card">
            <div class="flex items-center justify-between mb-1">
                <p class="text-gray-500 text-xs">今日有效订单</p>
                <i class="fa fa-file-text-o text-primary text-sm"></i>
            </div>
            <h3 class="text-xl font-bold" id="stat-orders">0</h3>
            <p class="text-[10px] text-gray-500">已完成/充电中</p>
        </div>
        <!-- 总耗电量 -->
        <div class="stat-card">
            <div class="flex items-center justify-between mb-1">
                <p class="text-gray-500 text-xs">总耗电量</p>
                <i class="fa fa-plug text-primary text-sm"></i>
            </div>
            <h3 class="text-xl font-bold" id="stat-power">0 度</h3>
            <p class="text-[10px] text-gray-500">今日累计</p>
        </div>
        <!-- 总收益 -->
        <div class="stat-card">
            <div class="flex items-center justify-between mb-1">
                <p class="text-gray-500 text-xs">总收益</p>
                <i class="fa fa-rmb text-success text-sm"></i>
            </div>
            <h3 class="text-xl font-bold" id="stat-income">¥0.00</h3>
            <p class="text-[10px] text-gray-500">仅已完成订单</p>
        </div>
    </div>
    <!-- 记录列表容器 -->
    <div class="bg-white rounded-lg border border-gray-200 shadow-sm overflow-hidden">
        <!-- 记录列表 -->
        <div id="records-list" class="divide-y divide-gray-100 p-2">
            <!-- 加载状态 -->
            <div class="flex items-center justify-center h-24 text-gray-400">
                <div class="text-center">
                    <i class="fa fa-spinner fa-spin text-base mb-2"></i>
                    <p class="text-sm">加载记录中...</p>
                </div>
            </div>
        </div>
        <!-- 空状态（默认隐藏） -->
        <div id="empty-state" class="hidden flex flex-col items-center justify-center p-8 text-gray-400">
            <div class="w-12 h-12 rounded-full bg-gray-100 flex items-center justify-center mb-3">
                <i class="fa fa-file-text-o text-xl"></i>
            </div>
            <h3 class="text-base font-medium mb-1">暂无充电记录</h3>
            <p class="text-xs text-center max-w-xs">完成充电后，记录将显示在这里</p>
        </div>
    </div>
</main>
<script>
    // ====================== 工具函数 ======================
    // 1. 生成日期key（如20250816）- 用于缓存区分日期
    function getDateKey(date) {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        return `${year}${month}${day}`;
    }

    // 2. 初始化并显示当前日期
    function initCurrentDate() {
        const now = new Date();
        const options = { year: 'numeric', month: 'short', day: 'numeric', weekday: 'short' };
        document.getElementById('current-date').textContent = now.toLocaleDateString('zh-CN', options);
        return now;
    }

    // 3. 格式化时间（HH:MM:SS）
    function formatTime(date) {
        const hour = String(date.getHours()).padStart(2, '0');
        const minute = String(date.getMinutes()).padStart(2, '0');
        const second = String(date.getSeconds()).padStart(2, '0');
        return `${hour}:${minute}:${second}`;
    }

    // 4. 计算两个时间的分钟差
    function getMinutesDiff(start, end) {
        // 确保开始时间在结束时间之前
        if (start >= end) return 0;
        return Math.floor((end - start) / (1000 * 60));
    }

    // 5. 生成不冲突的时间范围（设备级时间冲突检查）
    function generateValidTime(deviceUsedTimes, today, isCharging) {
        const now = new Date();
        const todayStart = new Date(today);
        todayStart.setHours(0, 0, 0, 0); // 当天0点
        let start, end;
        const maxAttempts = 20;
        let attempts = 0;

        do {
            attempts++;
            if (isCharging) {
                // 充电中：结束时间=当前时间，开始时间随机倒推（15分钟~8小时）
                const maxBackMinutes = 480; // 8小时上限
                const minBackMinutes = 15;  // 15分钟下限
                const backMinutes = Math.floor(Math.random() * (maxBackMinutes - minBackMinutes + 1)) + minBackMinutes;
                end = new Date(now);
                start = new Date(end);
                start.setMinutes(end.getMinutes() - backMinutes);
                // 确保开始时间不早于当天0点
                if (start < todayStart) start = new Date(todayStart);
            } else {
                // 已完成：结束时间≤当前时间-15分钟，开始时间随机（当天0点~结束时间-15分钟）
                const maxEnd = new Date(now);
                maxEnd.setMinutes(maxEnd.getMinutes() - 15); // 至少提前15分钟结束
                if (maxEnd < todayStart) maxEnd.setTime(todayStart.getTime());
                // 随机生成结束时间（当天1点~maxEnd）
                const endRange = maxEnd - new Date(todayStart.setHours(1, 0, 0, 0));
                const randomEndMs = Math.floor(Math.random() * endRange);
                end = new Date(todayStart.getTime() + randomEndMs);
                // 随机生成充电时长（15分钟~6小时）
                const maxDuration = 360; // 6小时上限
                const minDuration = 15;  // 15分钟下限
                const durationMinutes = Math.floor(Math.random() * (maxDuration - minDuration + 1)) + minDuration;
                start = new Date(end);
                start.setMinutes(end.getMinutes() - durationMinutes);
                // 确保开始时间不早于当天0点
                if (start < todayStart) start = new Date(todayStart);
            }

            // 强制确保开始时间在结束时间之前
            if (start >= end) {
                start = new Date(end);
                start.setMinutes(end.getMinutes() - 30); // 至少30分钟的差距
            }

            // 检查当前设备是否有时间冲突
            const isConflict = deviceUsedTimes.some(range =>
                (start >= range.start && start < range.end) ||
                (end > range.start && end <= range.end)
            );
            if (!isConflict) break;
        } while (attempts < maxAttempts);

        // 异常处理：多次尝试仍冲突则强制调整
        if (attempts >= maxAttempts) {
            end = new Date(now);
            end.setMinutes(end.getMinutes() - 15);
            start = new Date(end);
            start.setMinutes(end.getMinutes() - Math.floor(Math.random() * 120) + 15); // 15-135分钟随机时长

            // 最后检查，确保开始时间在结束时间之前
            if (start >= end) {
                start = new Date(end);
                start.setMinutes(end.getMinutes() - 30);
            }
        }

        // 计算充电量：充电量 = 时间差分钟数 * 7 / 60（保留1位小数，确保非负）
        const durationMinutes = getMinutesDiff(start, end);
        let power = (durationMinutes * 7) / 60;
        // 确保充电量非负
        power = Math.max(0, Number(power.toFixed(1)));

        return { start, end, power };
    }

    // 6. 打乱订单排序
    function shuffleOrders(orders) {
        return [...orders].sort(() => Math.random() - 0.5);
    }

    // 7. 检查是否是新的浏览器会话
    function isNewBrowserSession() {
        const lastSessionId = localStorage.getItem('sessionId');
        const currentSessionId = Date.now().toString(); // 使用时间戳作为会话ID

        // 如果没有上次会话ID，说明是新会话
        if (!lastSessionId) {
            localStorage.setItem('sessionId', currentSessionId);
            return true;
        }

        // 否则更新会话ID但返回false
        localStorage.setItem('sessionId', currentSessionId);
        return false;
    }

    // ====================== 数据生成 ======================
    // 生成当天充电记录
    function generateDayRecords(today, chargeData) {
        // 1. 从chargeData提取核心数据
        const targetValidOrders = Number(chargeData.orders) || 0; // 移除最小订单数限制
        const targetTotalPower = Number(chargeData.power) || 0;
        const targetTotalIncome = Number((targetTotalPower * 1.1).toFixed(2));

        const devices = ['设备1', '设备2', '设备3', '设备4', '设备5', '设备6', '设备7', '设备8', '设备9', '设备10'];
        // 定义状态列表
        const statusList = [
            { key: 'completed', text: '已完成', tagClass: 'bg-success/10 text-success', count: 0 },
            { key: 'charging', text: '充电中', tagClass: 'bg-primary/10 text-primary', count: 0 }
        ];

        // ====================== 新增：限制充电中订单最大占比 ======================
        const MAX_CHARGING_RATIO = 0.4; // 充电中订单最多占总订单的60%（可自定义调整，如0.5=50%）
        // 计算充电中订单的最大允许数量（向下取整）
        const maxChargingCount = targetValidOrders > 0
            ? Math.floor(targetValidOrders * MAX_CHARGING_RATIO)
            : 0;
        // 确保至少有1个已完成订单（避免总电量全部分给充电中订单）
        const minCompletedCount = targetTotalPower > 0 ? 1 : 0;
        // ======================================================================

        // 2. 分配已完成和充电中的订单数量（新增限制逻辑）
        if (targetValidOrders === 0) {
            // 订单数为0时，不生成任何记录
            statusList[0].count = 0;
            statusList[1].count = 0;
        } else if (targetValidOrders === 1) {
            // 只有1个订单时：若有总电量则强制为已完成，否则随机
            const isCharging = targetTotalPower === 0 && Math.random() > 0.5;
            statusList[0].count = isCharging ? 0 : 1;
            statusList[1].count = isCharging ? 1 : 0;
        } else {
            // 多个订单时：先按原逻辑随机分配，再强制限制充电中订单数量
            let baseCompletedCount = Math.max(1, Math.min(targetValidOrders - 1, Math.floor(Math.random() * targetValidOrders)));
            let baseChargingCount = targetValidOrders - baseCompletedCount;

            // 核心限制：若充电中订单超过最大允许数量，强制减少并增加已完成订单
            if (baseChargingCount > maxChargingCount) {
                baseChargingCount = maxChargingCount;
                baseCompletedCount = targetValidOrders - baseChargingCount;
            }

            // 确保已完成订单不低于最小要求（至少1个，避免总电量无法分摊）
            baseCompletedCount = Math.max(baseCompletedCount, minCompletedCount);
            baseChargingCount = targetValidOrders - baseCompletedCount;

            statusList[0].count = baseCompletedCount;
            statusList[1].count = baseChargingCount;
        }

        const todayStr = today.toLocaleDateString('zh-CN');
        const dateKey = getDateKey(today);
        // 设备时间冲突管理：{设备名: [{start, end}]}
        const deviceTimeMap = devices.reduce((acc, dev) => ({ ...acc, [dev]: [] }), {});
        const records = [];
        const completedPowerList = [];

        // 3. 为已完成订单分配电量（优化后：均匀分配+小范围波动）
        const completedCountTotal = statusList[0].count;
        let remainingPower = targetTotalPower;

        if (completedCountTotal > 0 && targetTotalPower > 0) {
            // 计算平均电量（基础值）
            const basePower = targetTotalPower / completedCountTotal;
            // 最小电量限制（1度，避免过小）
            const minPowerPerOrder = Math.max(1, Number(basePower * 0.3).toFixed(1)); // 至少为平均值的30%或1度
            // 最大电量限制（平均值的2倍，避免过大）
            const maxPowerPerOrder = Math.max(minPowerPerOrder * 2, Number(basePower * 2).toFixed(1));

            // 前n-1个已完成订单：基于平均值±30%波动，并限制在[min, max]范围内
            for (let i = 0; i < completedCountTotal - 1; i++) {
                // 随机波动比例：-30% ~ +30%
                const fluctuation = (Math.random() - 0.5) * 0.6; // -0.3 ~ 0.3
                let p = Number((basePower * (1 + fluctuation)).toFixed(1));

                // 限制在[min, max]范围内
                p = Math.max(minPowerPerOrder, Math.min(maxPowerPerOrder, p));

                // 确保剩余电量足够分配给剩余订单（至少每个剩余订单能分到minPowerPerOrder）
                const remainingOrders = completedCountTotal - i - 1;
                const requiredMinRemaining = remainingOrders * minPowerPerOrder;
                if (remainingPower - p < requiredMinRemaining) {
                    p = remainingPower - requiredMinRemaining; // 减少当前分配，确保剩余订单有足够电量
                    p = Math.max(minPowerPerOrder, Number(p.toFixed(1))); // 确保不低于最小值
                }

                completedPowerList.push(p);
                remainingPower -= p;
                remainingPower = Number(remainingPower.toFixed(1)); // 保留1位小数，避免精度问题
            }

            // 最后一个已完成订单：分配剩余电量（确保在[min, max]范围内）
            let lastP = Number(remainingPower.toFixed(1));
            // 调整最后一个订单的电量，确保不超出范围且总和正确
            if (lastP < minPowerPerOrder) {
                // 若最后一个订单电量不足，从前面的订单中匀出一些
                const need = minPowerPerOrder - lastP;
                for (let i = 0; i < completedPowerList.length && need > 0; i++) {
                    const canTake = Math.min(completedPowerList[i] - minPowerPerOrder, need);
                    if (canTake > 0) {
                        completedPowerList[i] = Number((completedPowerList[i] - canTake).toFixed(1));
                        lastP += canTake;
                        need -= canTake;
                    }
                }
                lastP = Math.max(minPowerPerOrder, Number(lastP.toFixed(1)));
            } else if (lastP > maxPowerPerOrder) {
                // 若最后一个订单电量过高，分摊给前面的订单
                const excess = lastP - maxPowerPerOrder;
                const addPerOrder = Number((excess / completedPowerList.length).toFixed(1));
                completedPowerList.forEach((_, i) => {
                    const newVal = completedPowerList[i] + addPerOrder;
                    completedPowerList[i] = Math.min(maxPowerPerOrder, Number(newVal.toFixed(1)));
                });
                lastP = maxPowerPerOrder;
            }
            completedPowerList.push(lastP);

            // 最终校准：确保总和等于目标总电量（处理精度误差）
            const total = completedPowerList.reduce((sum, p) => sum + p, 0);
            const diff = Number((targetTotalPower - total).toFixed(1));
            if (diff !== 0) {
                // 将误差分配给最后一个订单
                completedPowerList[completedPowerList.length - 1] = Number((completedPowerList[completedPowerList.length - 1] + diff).toFixed(1));
            }
        }

        // 4. 生成订单数据
        let completedPowerIdx = 0;
        for (const status of statusList) {
            for (let i = 0; i < status.count; i++) {
                // 随机选设备
                let randomDev;
                if (status.key === 'charging') {
                    // 筛选无充电中的设备
                    const availableDevs = devices.filter(dev =>
                        !deviceTimeMap[dev].some(range => range.status === 'charging')
                    );
                    randomDev = availableDevs[Math.floor(Math.random() * availableDevs.length)] || devices[Math.floor(Math.random() * devices.length)];
                } else {
                    // 已完成设备随机选择
                    randomDev = devices[Math.floor(Math.random() * devices.length)];
                }

                // 生成时间和电量
                let timePowerData, power;
                if (status.key === 'completed') {
                    // 已完成：用预分配的电量
                    power = completedPowerList[completedPowerIdx++] || 0;
                    // 确保电量非负
                    power = Math.max(0, power);

                    // 基于电量反算时长（分钟）
                    const durationMinutes = Math.max(1, Math.round((power * 60) / 7)); // 至少1分钟

                    // 生成符合时长的时间
                    const now = new Date();
                    const maxEnd = new Date(now);
                    maxEnd.setMinutes(maxEnd.getMinutes() - 15);
                    const todayStart = new Date(today);
                    todayStart.setHours(0, 0, 0, 0);

                    // 随机生成结束时间
                    const endRange = maxEnd - new Date(todayStart.setHours(1, 0, 0, 0));
                    const randomEndMs = endRange > 0 ? Math.floor(Math.random() * endRange) : 0;
                    const end = new Date(todayStart.getTime() + randomEndMs);

                    // 计算开始时间（结束时间 - 时长）
                    let start = new Date(end);
                    start.setMinutes(end.getMinutes() - durationMinutes);

                    // 确保开始时间在结束时间之前且不早于当天0点
                    if (start >= end) {
                        start = new Date(end);
                        start.setMinutes(end.getMinutes() - Math.max(1, durationMinutes));
                    }
                    if (start < todayStart) start = new Date(todayStart);

                    timePowerData = { start, end, power };
                } else {
                    // 充电中：生成随机时间和电量
                    timePowerData = generateValidTime(
                        deviceTimeMap[randomDev],
                        today,
                        true
                    );
                    power = timePowerData.power;
                }

                let { start, end } = timePowerData;
                // 再次确保开始时间在结束时间之前
                if (start >= end) {
                    start = new Date(end);
                    start.setMinutes(end.getMinutes() - 30);
                }

                const startStr = `${todayStr} ${formatTime(start)}`;
                const endStr = status.key === 'charging'
                    ? '充电中...'
                    : `${todayStr} ${formatTime(end)}`;

                // 计算金额
                const amount = status.key === 'completed'
                    ? (power * 1.1).toFixed(2)
                    : '0.00';

                // 生成订单号
                const randomStr = Math.random().toString(36).toUpperCase().substr(2, 6);
                const orderNo = `CD${dateKey}${Math.floor(Math.random() * 10)}${randomStr}`;

                // 记录设备时间
                deviceTimeMap[randomDev].push({
                    start,
                    end,
                    status: status.key === 'charging' ? 'charging' : 'completed'
                });

                // 加入记录
                records.push({
                    id: `${orderNo}-${Date.now()}`,
                    device: randomDev,
                    orderNo,
                    startStr,
                    endStr,
                    start: start.getTime(),
                    end: end.getTime(),
                    power: Math.max(0, power), // 确保充电量非负
                    status: status.text,
                    statusClass: status.tagClass,
                    isCounted: true,
                    amount,
                    isCompleted: status.key === 'completed'
                });
            }
        }

        // 5. 确保订单总数与目标一致
        if (records.length !== targetValidOrders) {
            console.warn(`订单数不匹配（${records.length}≠${targetValidOrders}），重新调整`);
            // 调整订单数量
            if (records.length < targetValidOrders) {
                const 补足数量 = targetValidOrders - records.length;
                for (let i = 0; i < 补足数量; i++) {
                    // 补充充电中订单
                    const availableDevs = devices.filter(dev =>
                        !deviceTimeMap[dev].some(range => range.status === 'charging')
                    );
                    const randomDev = availableDevs[Math.floor(Math.random() * availableDevs.length)] || devices[0];
                    const timePowerData = generateValidTime(deviceTimeMap[randomDev], today, true);
                    const { start, end, power } = timePowerData;
                    const startStr = `${todayStr} ${formatTime(start)}`;
                    const endStr = '充电中...';
                    const amount = '0.00';
                    const randomStr = Math.random().toString(36).toUpperCase().substr(2, 6);
                    const orderNo = `CD${dateKey}${Math.floor(Math.random() * 10)}${randomStr}`;

                    deviceTimeMap[randomDev].push({ start, end, status: 'charging' });
                    records.push({
                        id: `${orderNo}-${Date.now()}`,
                        device: randomDev,
                        orderNo,
                        startStr,
                        endStr,
                        start: start.getTime(),
                        end: end.getTime(),
                        power: Math.max(0, power),
                        status: '充电中',
                        statusClass: 'bg-primary/10 text-primary',
                        isCounted: true,
                        amount,
                        isCompleted: false
                    });
                }
            } else {
                // 减少订单数量
                const needDelete = records.length - targetValidOrders;
                for (let i = 0; i < needDelete; i++) {
                    records.pop();
                }
            }
        }

        // 6. 打乱订单排序
        const shuffledRecords = shuffleOrders(records);

        return {
            records: shuffledRecords,
            stats: {
                validOrders: targetValidOrders,
                totalPower: targetTotalPower,
                totalIncome: targetTotalIncome
            }
        };
    }

    // ====================== 渲染逻辑 ======================
    // 渲染记录列表
    function renderRecords(records) {
        const listEl = document.getElementById('records-list');
        const emptyEl = document.getElementById('empty-state');

        if (records.length === 0) {
            listEl.innerHTML = '';
            emptyEl.classList.remove('hidden');
            return;
        }
        emptyEl.classList.add('hidden');

        listEl.innerHTML = '';
        records.forEach(record => {
            const amountText = `¥${record.amount}`;
            const amountClass = record.isCompleted ? 'text-success font-medium' : 'text-gray-600';

            const recordHtml = `
        <div class="record-card p-3">
            <!-- 顶部：设备+状态 -->
            <div class="flex justify-between items-start mb-2">
                <span class="text-sm font-medium">${record.device}</span>
                <span class="status-tag ${record.statusClass}">${record.status}</span>
            </div>

            <!-- 中部：订单号+电量 -->
            <div class="grid grid-cols-2 gap-1 mb-2 text-xs">
                <div>
                    <p class="text-gray-500">订单号</p>
                    <p class="text-truncate text-gray-700">${record.orderNo}</p>
                </div>
                <div>
                    <p class="text-gray-500">充电量</p>
                    <p class="text-gray-700">${record.power} 度</p>
                </div>
            </div>

            <!-- 下部：时间+金额 -->
            <div class="grid grid-cols-2 gap-1 text-xs mb-2">
                <div>
                    <p class="text-gray-500">开始时间</p>
                    <p class="text-gray-600">${record.startStr}</p>
                </div>
                <div>
                    <p class="text-gray-500">结束时间</p>
                    <p class="text-gray-600">${record.endStr}</p>
                </div>
            </div>
            <div class="flex justify-end items-center text-xs">
                <div>
                    <p class="text-gray-500">费用</p>
                    <p class="${amountClass}">${amountText}</p>
                </div>
            </div>
        </div>
    `;
            listEl.innerHTML += recordHtml;
        });
    }

    // 更新统计数据
    function updateStats(chargeData) {
        const validOrders = Number(chargeData.orders) || 0;
        const totalPower = Number(chargeData.power) || 0;
        const totalIncome = Number((totalPower * 1.1).toFixed(2));

        document.getElementById('stat-orders').textContent = validOrders;
        document.getElementById('stat-power').textContent = `${totalPower} 度`;
        document.getElementById('stat-income').textContent = `¥${totalIncome.toFixed(2)}`;
    }

    // 主渲染函数
    function renderChargingPage() {
        const today = initCurrentDate();
        const dateKey = getDateKey(today);
        const now = new Date().getTime();
        const isNewSession = isNewBrowserSession();

        // 1. 读取并处理localStorage.chargeData
        let chargeData = JSON.parse(localStorage.getItem('chargeData') || '{}');
        // 补全默认值
        if (chargeData.orders === undefined || isNaN(chargeData.orders)) chargeData.orders = 0;
        if (chargeData.power === undefined || isNaN(chargeData.power)) chargeData.power = 0;
        // 强制转数字
        chargeData.orders = Math.floor(Number(chargeData.orders));
        chargeData.power = Number(chargeData.power);
        // 确保订单数非负
        chargeData.orders = Math.max(0, chargeData.orders);
        chargeData.power = Math.max(0, chargeData.power);
        // 保存回localStorage
        localStorage.setItem('chargeData', JSON.stringify(chargeData));

        // 2. 处理缓存（只有新会话或日期变更时才生成新数据）
        let cache = JSON.parse(localStorage.getItem('chargingCache') || '{}');
        let finalRecords;

        // 缓存判断：新会话/新日期/chargeData变化时重新生成记录
        if (!cache || isNewSession || cache.dateKey !== dateKey ||
            cache.chargeDataOrders !== chargeData.orders ||
            cache.chargeDataPower !== chargeData.power) {
            const newData = generateDayRecords(today, chargeData);
            finalRecords = newData.records;
            // 缓存数据
            cache = {
                dateKey,
                chargeDataOrders: chargeData.orders,
                chargeDataPower: chargeData.power,
                records: finalRecords.map(r => ({ ...r, isImmutable: r.status === '已完成' }))
            };
            localStorage.setItem('chargingCache', JSON.stringify(cache));
        } else {
            // 缓存有效：仅更新充电中订单的时间
            finalRecords = cache.records.map(record => {
                if (record.status === '充电中' && !record.isImmutable) {
                    const start = new Date(record.start);
                    const end = new Date(now);

                    // 确保开始时间在结束时间之前
                    if (start >= end) {
                        start.setTime(end.getTime() - 30 * 60 * 1000); // 30分钟前
                    }

                    // 重新计算电量（确保非负）
                    const durationMinutes = getMinutesDiff(start, end);
                    let power = (durationMinutes * 7) / 60;
                    power = Math.max(0, Number(power.toFixed(1)));

                    return {
                        ...record,
                        end: end.getTime(),
                        endStr: '充电中...',
                        power,
                        amount: '0.00'
                    };
                }
                return record;
            });
        }

        // 3. 最终校验订单总数
        if (finalRecords.length !== chargeData.orders) {
            console.error(`缓存订单数异常（${finalRecords.length}≠${chargeData.orders}），重新生成`);
            const newData = generateDayRecords(today, chargeData);
            finalRecords = newData.records;
            cache.records = finalRecords.map(r => ({ ...r, isImmutable: r.status === '已完成' }));
            localStorage.setItem('chargingCache', JSON.stringify(cache));
        }

        // 4. 渲染页面
        updateStats(chargeData);
        renderRecords(finalRecords);

        // 5. 定时刷新（30分钟更新一次充电中订单）
        setTimeout(renderChargingPage, 1800000);
    }

    // ====================== 页面初始化 ======================
    window.addEventListener('DOMContentLoaded', renderChargingPage);
    // 监听localStorage变化
    window.addEventListener('storage', (e) => {
        if (e.key === 'chargeData') {
            renderChargingPage();
        }
    });
</script>
</body>
</html>